package com.htudata.core.util.operation;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class CollectionsOperationUtils {

  public static boolean isValidCollection(Collection collection) {
    if (collection != null && 
      !collection.isEmpty())
      return true; 
    return false;
  }
  
  public static <T> T[] listToArr(List<T> list, Object[] arr) {
    Object[] result = list.toArray(arr);
    return (T[])result;
  }
  
  public static <K, V> Map<K, V> listToMap(List<V> list, String keyField, Map<K, V> result)  throws Exception  {
    for (V value : list) {
      K key = (K)ClassOperationUtils.executeGetter(value, keyField, new Class[0]);
      result.put(key, value);
    } 
    return result;
  }
  
  public static <K, V, O> Map<K, V> listToMap(List<O> list, String keyField, String valueField, Map<K, V> result)  throws Exception  {
    for (O obj : list) {
      K key = (K)ClassOperationUtils.executeGetter(obj, keyField, new Class[0]);
      V value = (V)ClassOperationUtils.executeGetter(obj, valueField, new Class[0]);
      result.put(key, value);
    } 
    return result;
  }
  
  public static List<String> transferStrToList(String srcStr) {
    List<String> result = new ArrayList<>();
    byte b;
    int i;
    String[] arrayOfString;
    for (i = (arrayOfString = srcStr.split(",")).length, b = 0; b < i; ) {
      String str = arrayOfString[b];
      result.add(str);
      b++;
    } 
    return result;
  }
  
  public static <T> void removeFirstNull(List<T> list) {
    list.remove((Object)null);
  }
  
  public static <T> void removeAllNull(List<T> list) {
    list.removeAll(Collections.singleton(null));
  }
  
  public static <T> List<T> subList(List<T> list, int newListSize, boolean fromBeginToEnd) {
    int listSize = list.size();
    if (newListSize > listSize)
      newListSize = listSize; 
    int beginIndex = 0;
    int endIndex = -1;
    if (fromBeginToEnd) {
      endIndex = newListSize;
    } else {
      beginIndex = list.size() - newListSize;
      endIndex = beginIndex + newListSize;
    } 
    List<T> result = list.subList(beginIndex, endIndex);
    return result;
  }
  
  public static <T> void removeDuplicated(List<T> list) {
    Set<T> set = new HashSet<>(list);
    list.clear();
    list.addAll(set);
  }
  
  public static <T> void reverse(List<T> list) {
    Collections.reverse(list);
  }
  
  public static void sort(List<String> list) {
    Collections.sort(list);
  }
  
  public static void sortDesc(List<String> list)  throws Exception  {
    Collections.sort(list, new Comparator<String>() {
      @Override
      public int compare(String o1, String o2) {
        int result = o1.compareTo(o2);
        return result;
      }

    });
  }
  
  public static <T> void sortByField(List<T> list, final String sortField)  throws Exception  {
    Collections.sort(list, new Comparator<T>() {
          public int compare(Object obj1, Object obj2) {
            T t1 = (T)obj1;
            T t2 = (T)obj2;
              String value1 = null;
              try {
                  value1 = (String) ClassOperationUtils.executeMethod(t1,
                      ClassOperationUtils.getGetter(t1, sortField, new Class[0]), new Object[0]);
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
              String value2 = null;
              try {
                  value2 = (String) ClassOperationUtils.executeMethod(t2,
                    ClassOperationUtils.getGetter(t2, sortField, new Class[0]), new Object[0]);
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
              int result = value1.compareTo(value2);
            return result;
          }
        });
  }
  
  public static <T> void sortByFieldDesc(List<T> list, final String field)  throws Exception  {
    Collections.sort(list, new Comparator<T>() {
          public int compare(Object obj1, Object obj2) {
            T t1 = (T)obj1;
            T t2 = (T)obj2;
              String value1 = null;
              try {
                  value1 = (String) ClassOperationUtils.executeMethod(t1,
                      ClassOperationUtils.getGetter(t1, field, new Class[0]), new Object[0]);
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
              String value2 = null;
              try {
                  value2 = (String) ClassOperationUtils.executeMethod(t2,
                    ClassOperationUtils.getGetter(t2, field, new Class[0]), new Object[0]);
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
              int result = value2.compareTo(value1);
            return result;
          }
        });
  }
  
  public static <T> void sortByDoubleField(List<T> list, final String sortField) throws Exception  {
    Collections.sort(list, new Comparator<T>() {
          public int compare(Object obj1, Object obj2) {
            T t1 = (T)obj1;
            T t2 = (T)obj2;
              Double value1 = null;
              try {
                  value1 = Double.valueOf(Double.parseDouble(
                        (String) ClassOperationUtils.executeMethod(t1, ClassOperationUtils.getGetter(t1, sortField, new Class[0]), new Object[0])));
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
              Double value2 = null;
              try {
                  value2 = Double.valueOf(Double.parseDouble(
                      (String) ClassOperationUtils.executeMethod(t2, ClassOperationUtils.getGetter(t2, sortField, new Class[0]), new Object[0])));
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
              int result = value1.compareTo(value2);
            return result;
          }
        });
  }
  
  public static <T> void sortByLongField(List<T> list, final String sortField, final String sortType) {
    Collections.sort(list, new Comparator<T>() {
          public int compare(Object obj1, Object obj2) {
            T t1 = (T)obj1;
            T t2 = (T)obj2;
              Long value1 = null;
              try {
                  value1 = (Long) ClassOperationUtils.executeGetter(t1, sortField, new Class[0]);
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
              Long value2 = null;
              try {
                  value2 = (Long) ClassOperationUtils.executeGetter(t2, sortField, new Class[0]);
              } catch (Exception e) {
                  throw new RuntimeException(e);
              }
              int result = 0;
            if ("asc".equals(sortType)) {
              result = value1.compareTo(value2);
              return result;
            } 
            if ("desc".equals(sortType)) {
              result = value2.compareTo(value1);
              return result;
            } 
            return result;
          }
        });
  }
}
